package cn.qingyun.gis.modules.init.system.sso;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.qingyun.gis.cache.common.facade.CacheFacade;
import cn.qingyun.gis.cache.constant.CacheConstant;
import cn.qingyun.gis.common.Result;
import cn.qingyun.gis.modules.init.system.constant.CommonConstant;
import cn.qingyun.gis.modules.init.system.entity.SysUser;
import cn.qingyun.gis.modules.init.system.service.IBaseCommonService;
import cn.qingyun.gis.modules.init.system.service.ISysUserService;
import cn.qingyun.gis.modules.init.system.sso.crm.CrmAuthItem;
import cn.qingyun.gis.modules.init.system.sso.request.SsoLoginRequest;
import cn.qingyun.gis.modules.init.system.sso.request.SsoLoginResponse;
import cn.qingyun.gis.modules.init.system.sso.request.SsoValidTokenRequest;
import cn.qingyun.gis.modules.init.system.sso.utils.CrmTool;
import cn.qingyun.gis.modules.init.system.vo.LoginUser;
import cn.qingyun.gis.modules.init.utils.JwtUtil;
import cn.qingyun.gis.modules.init.utils.MD5Util;
import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/admin/sso")
public class SsoLoginController {
    @Resource
    private ISysUserService iSysUserService;
    @Resource
    private IBaseCommonService iBaseCommonService;

    @PostMapping("/login")
    public Result<?> login(@RequestBody @Validated SsoLoginRequest request) {
        List<CrmAuthItem> authItems = CrmTool.authGrigList(request.getCrmAccount());

        // 保证自动同步系统用户， 前提是有guest 权限
        SysUser sysUser = iSysUserService.ensureUserIsValidWithGuestAuth(request.getCrmAccount(), request.getPhoneNumber(), StrUtil.firstNonEmpty(request.getCrmAccount(), request.getPhoneNumber()));
        String token = JwtUtil.sign(sysUser.getUsername(), MD5Util.MD5Encode(sysUser.getPassword(), StandardCharsets.UTF_8.name()));
        CacheFacade.set(CommonConstant.PREFIX_USER_TOKEN + token, token, JwtUtil.EXPIRE_TIME / 1000);
        CacheFacade.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);

        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(sysUser, loginUser);
        loginUser.setPassword(SecureUtil.md5(sysUser.getPassword()));
        CacheFacade.set(CacheConstant.SYS_USERS_CACHE_JWT + ":" + token, loginUser, JwtUtil.EXPIRE_TIME / 1000);
        CacheFacade.expire(CacheConstant.SYS_USERS_CACHE_JWT + ":" + token, JwtUtil.EXPIRE_TIME / 1000);

        iBaseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功！", CommonConstant.LOG_TYPE_1, null, loginUser);

        return Result.okData(SsoLoginResponse.builder().token(token).build());
    }

    @PostMapping("/valid")
    public Result<?> valid(@RequestBody @Validated SsoValidTokenRequest request) {
        String requestToken = request.getToken();
        String username = JwtUtil.getUsername(requestToken);
        if (username == null) {
            throw new AuthenticationException("非法令牌，请重新登录!");
        }

        // 查询用户信息
        LoginUser loginUser = (LoginUser) CacheFacade.get(CacheConstant.SYS_USERS_CACHE_JWT + ":" + requestToken);
        //如果redis缓存用户信息为空，则通过接口获取用户信息,避免超过两个小时操作中token过期
        if (Objects.isNull(loginUser)) {
            throw new AuthenticationException("无效操作时间过长，请重新登录!");
        }
        // 判断用户状态
        if (loginUser.getStatus() != 1) {
            throw new AuthenticationException("账号已被锁定,请联系管理员!");
        }

        Result<?> result = Result.okData("登录成功");

        SysUser sysUser = iSysUserService.getUserByWorkNo(loginUser.getWorkNo(), loginUser.getPhone());
        if (ObjectUtil.isNull(sysUser)) {
            throw new AuthenticationException("无效的用户，请联系管理员!");
        }
        iSysUserService.repackUserInfo(sysUser, (Result<JSONObject>) result);
        BeanUtils.copyProperties(sysUser, loginUser);

        return result;
    }
}
